// 指定当前类所属的包路径，用于组织项目结构
package com.example.springboot.service.impl;
// 导入所需的类和工具包
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.springboot.common.JudgeBedName;
import com.example.springboot.entity.AdjustRoom;
import com.example.springboot.entity.DormRoom;
import com.example.springboot.mapper.DormRoomMapper;
import com.example.springboot.service.DormRoomService;
import org.springframework.stereotype.Service;
// 导入资源注入注解（用于依赖注入）
import javax.annotation.Resource;
// 导入自定义工具类中的静态方法（计算房间人数）
import static com.example.springboot.common.CalPeopleNum.calNum;

// @Service：声明当前类是 Spring 管理的服务层组件，自动注册到 Spring 容器中
@Service
// 继承 ServiceImpl 实现服务层接口，泛型参数为 Mapper 接口和实体类
public class DormRoomImpl extends ServiceImpl<DormRoomMapper, DormRoom> implements DormRoomService {
    // @Resource：注入 DAO 层对象（按名称注入 DormRoomMapper 接口的实现类）
    @Resource
    private DormRoomMapper dormRoomMapper;

    /**
     * 首页顶部：空宿舍统计（当前人数 < 4 的房间数）
     * @return 空宿舍数量
     */
    @Override// 标识重写父类方法
    public int notFullRoom() {// 创建查询条件构造器
        QueryWrapper<DormRoom> qw = new QueryWrapper<>();
        // 添加条件：当前人数（current_capacity）小于 4
        qw.lt("current_capacity", 4);
        // 执行统计查询（返回符合条件的记录数，转为 int 类型）
        int notFullRoomNum = Math.toIntExact(dormRoomMapper.selectCount(qw));
        return notFullRoomNum;
    }

    /**
     * 添加房间
     * @param dormRoom 待添加的宿舍房间实体对象
     * @return 影响的行数（成功返回 1，失败返回 0）
     */
    @Override
    public int addNewRoom(DormRoom dormRoom) {
        // 执行插入操作（调用 MyBatis-Plus 基础 Mapper 的插入方法）
        int insert = dormRoomMapper.insert(dormRoom);
        return insert;
    }

    /**
     * 分页查询房间（按房间号模糊搜索）
     * @param pageNum 当前页码
     * @param pageSize 每页显示记录数
     * @param search 搜索关键词
     * @return 分页结果对象（包含总记录数和当前页数据）
     */
    @Override
    public Page find(Integer pageNum, Integer pageSize, String search) {
        // 创建分页对象（传入页码和每页大小）
        Page page = new Page<>(pageNum, pageSize);
        // 创建查询条件构造器
        QueryWrapper<DormRoom> qw = new QueryWrapper<>();
        // 添加条件：房间号（dormroom_id）模糊匹配搜索词
        qw.like("Dormroom_id", search);
        // 注意：数据库字段名若为驼峰命名，需与实体类属性名对应（此处假设字段为 dormroom_id）
        // 执行分页查询（调用 Mapper 的分页查询方法）
        Page roomPage = dormRoomMapper.selectPage(page, qw);
        return roomPage;
    }

    /**
     * 更新房间（根据 ID 更新）
     * @param dormRoom 包含更新后数据的房间实体对象（需包含 ID）
     * @return 影响的行数（成功返回 1，失败返回 0）
     */
    @Override
    public int updateNewRoom(DormRoom dormRoom) {
        // 执行更新操作（调用 MyBatis-Plus 基础 Mapper 的根据 ID 更新方法）
        int i = dormRoomMapper.updateById(dormRoom);
        return i;
    }

    /**
     * 删除房间（根据房间 ID 删除）
     * @param dormRoomId 待删除房间的 ID
     * @return 影响的行数（成功返回 1，失败返回 0）
     */
    @Override
    public int deleteRoom(Integer dormRoomId) {
        // 执行删除操作（调用 MyBatis-Plus 基础 Mapper 的根据 ID 删除方法）
        int i = dormRoomMapper.deleteById(dormRoomId);
        return i;
    }

    /**
     * 删除床位上的学生信息（更新床位字段为 null，并减少当前人数）
     * @param bedName 床位名称（如 "first_bed"）
     * @param dormRoomId 房间 ID
     * @param calCurrentNum 当前人数（调用工具类计算后的结果）
     * @return 影响的行数（成功返回 1，失败返回 0）
     */
    @Override
    public int deleteBedInfo(String bedName, Integer dormRoomId, int calCurrentNum) {
        // 创建更新条件构造器
        UpdateWrapper updateWrapper = new UpdateWrapper();
        // 添加条件：匹配房间 ID
        updateWrapper.eq("dormroom_id", dormRoomId);
        // 设置床位字段为 null（删除学生信息）
        updateWrapper.set(bedName, null);
        // 设置当前人数为原人数减 1
        updateWrapper.set("current_capacity", calCurrentNum - 1);
        // 执行更新操作（无需指定实体对象，直接通过条件构造器更新）
        int update = dormRoomMapper.update(null, updateWrapper);
        return update;

    }

    /**
     * 检查学生是否已有床位（查询四个床位字段是否包含该学生用户名）
     * @param username 学生用户名
     * @return 存在床位则返回房间实体，否则返回 null
     */
    @Override
    public DormRoom judgeHadBed(String username) {
        // 创建查询条件构造器
        QueryWrapper qw = new QueryWrapper();
        // 添加条件：第一个床位等于用户名
        qw.eq("first_bed", username);
        // 添加 OR 条件：第二个床位等于用户名
        qw.or();
        qw.eq("second_bed", username);
        qw.or();
        qw.eq("third_bed", username);
        qw.or();
        qw.eq("fourth_bed", username);
        DormRoom dormRoom = dormRoomMapper.selectOne(qw);
        return dormRoom;
    }

    /**
     * 主页：统计所有住宿学生人数（四个床位非空记录数总和）
     * @return 总住宿人数
     */
    @Override
    public Long selectHaveRoomStuNum() {
        // 查询第一个床位非空的房间数
        QueryWrapper<DormRoom> qw1 = new QueryWrapper<>();
        qw1.isNotNull("first_bed");
        Long first_bed = dormRoomMapper.selectCount(qw1);
        // 查询第二个床位非空的房间数
        QueryWrapper<DormRoom> qw2 = new QueryWrapper<>();
        qw2.isNotNull("second_bed");
        Long second_bed = dormRoomMapper.selectCount(qw2);
        // 查询第三个床位非空的房间数
        QueryWrapper<DormRoom> qw3 = new QueryWrapper<>();
        qw3.isNotNull("third_bed");
        Long third_bed = dormRoomMapper.selectCount(qw3);
        // 查询第四个床位非空的房间数
        QueryWrapper<DormRoom> qw4 = new QueryWrapper<>();
        qw4.isNotNull("fourth_bed");
        Long fourth_bed = dormRoomMapper.selectCount(qw4);
        // 计算总人数（每个床位非空数之和，因为每个床位对应一个学生）
        Long count = first_bed + second_bed + third_bed + fourth_bed;
        return count;
    }

    /**
     * 获取指定宿舍楼的学生总人数
     * @param dormBuildId 宿舍楼 ID
     * @return 该宿舍楼的住宿人数
     */
    @Override
    public Long getEachBuildingStuNum(int dormBuildId) {
        // 查询该宿舍楼中第一个床位非空的房间数
        QueryWrapper<DormRoom> qw1 = new QueryWrapper<>();
        qw1.eq("dormbuild_id", dormBuildId);
        qw1.isNotNull("first_bed");
        Long first_bed = dormRoomMapper.selectCount(qw1);
        // 查询该宿舍楼中第二个床位非空的房间数
        QueryWrapper<DormRoom> qw2 = new QueryWrapper<>();
        qw2.eq("dormbuild_id", dormBuildId);
        qw2.isNotNull("second_bed");
        Long second_bed = dormRoomMapper.selectCount(qw2);
        // 查询该宿舍楼中第三个床位非空的房间数
        QueryWrapper<DormRoom> qw3 = new QueryWrapper<>();
        qw3.eq("dormbuild_id", dormBuildId);
        qw3.isNotNull("third_bed");
        Long third_bed = dormRoomMapper.selectCount(qw3);
        // 查询该宿舍楼中第四个床位非空的房间数
        QueryWrapper<DormRoom> qw4 = new QueryWrapper<>();
        qw4.eq("dormbuild_id", dormBuildId);
        qw4.isNotNull("fourth_bed");
        Long fourth_bed = dormRoomMapper.selectCount(qw4);
        // 计算总人数（同楼层逻辑，各床位非空数之和）
        Long count = first_bed + second_bed + third_bed + fourth_bed;

        return count;
    }

    /**
     * 根据调宿申请表调整床位信息（核心业务逻辑）
     * @param adjustRoom 调宿申请表对象
     * @return 调整结果：1（成功）、-1（第一步失败）、-2（原床位无学生）
     */
    @Override
    public int adjustRoomUpdate(AdjustRoom adjustRoom) {
        // 解析调宿申请表中的参数
        String username = adjustRoom.getUsername();// 调宿学生用户名
        int currentRoomId = adjustRoom.getCurrentRoomId();// 原房间 ID
        // 原床位名称
        String currentBedName = JudgeBedName.getBedName(adjustRoom.getCurrentBedId());
        // 目标房间 ID
        int towardsRoomId = adjustRoom.getTowardsRoomId();
        // 目标床位名称
        String towardsBedName = JudgeBedName.getBedName(adjustRoom.getTowardsBedId());
        // 第一步：检查原房间的原床位是否有学生
        QueryWrapper qw = new QueryWrapper();
        qw.eq("dormroom_id", currentRoomId);// 条件：原房间 ID
        qw.isNotNull(currentBedName);// 条件：原床位字段非空（存在学生）
        DormRoom dormRoom1 = dormRoomMapper.selectOne(qw);// 查询原房间信息

        if (dormRoom1 == null) {
            return -2;// 原床位无学生，调整失败
        }
        int currentCapacity1 = calNum(dormRoom1);// 调用工具类计算原房间当前人数
        // 第二步：更新原房间，删除原床位学生信息
        UpdateWrapper uw1 = new UpdateWrapper();
        uw1.eq("dormroom_id", currentRoomId);// 条件：原房间 ID
        uw1.set(currentBedName, null);// 设置原床位为 null（删除学生）
        uw1.set("current_capacity", currentCapacity1 - 1);// 原房间人数减 1
        int result1 = dormRoomMapper.update(null, uw1);// 执行更新
        // 第三步：查询目标房间信息
        DormRoom dormRoom2 = dormRoomMapper.selectById(towardsRoomId);
        int currentCapacity2 = calNum(dormRoom2);// 计算目标房间当前人数

        if (result1 == 1) {// 原房间更新成功，继续处理目标房间
            // 第四步：更新目标房间，添加学生到目标床位
            UpdateWrapper uw2 = new UpdateWrapper();
            uw2.eq("dormroom_id", towardsRoomId);// 条件：目标房间 ID
            uw2.set(towardsBedName, username);// 设置目标床位为学生用户名
            uw2.set("current_capacity", currentCapacity2 + 1); // 目标房间人数加 1
            int result2 = dormRoomMapper.update(null, uw2);// 执行更新
            return result2;// 返回目标房间更新结果（1 表示成功，0 表示失败）
        }
        return -1;// 原房间更新失败
    }


    /**
     * 检查房间是否未满（当前人数 < 4）
     * @param dormRoomId 房间 ID
     * @return 存在未满房间则返回实体，否则返回 null
     */
    @Override
    public DormRoom checkRoomState(Integer dormRoomId) {
        QueryWrapper qw = new QueryWrapper();
        qw.eq("dormroom_id", dormRoomId);// 条件：匹配房间 ID
        qw.lt("current_capacity", 4);// 条件：当前人数小于 4
        DormRoom dormRoom = dormRoomMapper.selectOne(qw);
        return dormRoom;
    }

    /**
     * 检查房间是否存在（根据 ID 查询）
     * @param dormRoomId 房间 ID
     * @return 存在则返回实体，否则返回 null
     */
    @Override
    public DormRoom checkRoomExist(Integer dormRoomId) {
        DormRoom dormRoom = dormRoomMapper.selectById(dormRoomId);
        // 调用 Mapper 的根据 ID 查询方法
        return dormRoom;
    }


    /**
     * 检查床位是否为空（床位字段为 null）
     * @param dormRoomId 房间 ID
     * @param bedNum 床位编号（1-4）
     * @return 床位为空则返回房间，否则返回 null
     */
    @Override
    public DormRoom checkBedState(Integer dormRoomId, int bedNum) {
        QueryWrapper qw = new QueryWrapper();
        qw.eq("dormroom_id", dormRoomId);// 条件：匹配房间 ID
        qw.isNull(JudgeBedName.getBedName(bedNum));// 条件：通过工具类获取床位名称并判断为 null
        DormRoom dormRoom = dormRoomMapper.selectOne(qw);
        return dormRoom;
    }


}
